package net.zoneland.knowledge.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import net.zoneland.knowledge.config.TalkConfig;
import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.model.security.OperationContextHolder;
import net.zoneland.knowledge.utils.LoggerHelper;

/**
 * IndexController.
 *
 * @author: bcc
 * 2021/5/28
 */
@Controller
@RequestMapping("/index")
public class IndexController {

    /**
     * 日志.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(IndexController.class);

    /**
     * 是否pc模拟手机端.
     */
    public static final String FIELD_TESTONPC = "testonpc";

    /**
     * 敏行moa token参数.
     */
    public static final String FIELD_MX_SSO_TOKEN = "mx_sso_token";

    /**
     * token参数名.
     */
    public static final String FIELD_TOKEN = "token";

    /**
     * 机器人地址配置.
     */
    @Autowired
    private TalkConfig talkConfig;

    /**
     * 机器人-智办入口.
     * @param request 请求request
     * @param response 响应
     * @throws IOException 异常
     */
    @GetMapping(value = "/talkzb.htm")
    public void tokenZb(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        final String url = talkConfig.getUrl() + "/#/?showZb=true&token=" + OperationContextHolder.getPrincipal().getAttrMap()
                .get(Constants.TOKEN_NAME) + getParam(request);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("talk.htm sendRedirect url:{}", LoggerHelper.replaceBreakCharacters(url));
        }
        // url前缀配置在配置文件，加判断防止sonar报错
        if (!StringUtils.startsWith(url, talkConfig.getUrl())) {
            return;
        }
        response.sendRedirect(url);
    }

    /**
     * PC端入口地址.
     * @param request 请求request
     * @param response 响应
     * @throws IOException 异常
     */
    @GetMapping(value = "/talk.htm")
    public void token(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        // 这种url不能使用UriComponentsBuilder
        final String url = talkConfig.getUrl() + "/#/?token=" + OperationContextHolder.getPrincipal().getAttrMap()
            .get(Constants.TOKEN_NAME) + getParam(request);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("talk.htm sendRedirect url:{}", LoggerHelper.replaceBreakCharacters(url));
        }
        if (!StringUtils.startsWith(url, talkConfig.getUrl())) {
            return;
        }
        response.sendRedirect(url);
    }

    /**
     * moa入口.
     * @param request 请求
     * @param response 响应
     * @throws IOException 异常
     */
    @GetMapping(value = "moatalk.htm")
    public void moatalk(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
        final String testOnPc = request.getParameter(FIELD_TESTONPC);
        final String mxSsoToken = request.getParameter(FIELD_MX_SSO_TOKEN);
        final String moaUrl = BooleanUtils.toBoolean(testOnPc) ? talkConfig.getMoaTestUrl() : talkConfig.getMoaUrl();
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("moatalk.htm访问，testOnPc:{}，mxSsoToken:{}，moaUrl:{}，", testOnPc, mxSsoToken, moaUrl);
        }
        final UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(moaUrl).
            queryParam(FIELD_TOKEN, OperationContextHolder.getPrincipal().getAttrMap().get(Constants.TOKEN_NAME))
            .queryParam(FIELD_TESTONPC, testOnPc)
            .queryParam(FIELD_MX_SSO_TOKEN, mxSsoToken);
        final String url = builder.build(true).encode() + getParam(request);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("moatalk.htm sendRedirect url:{}", LoggerHelper.replaceBreakCharacters(url));
        }
        if (!StringUtils.startsWith(url, moaUrl)) {
            return;
        }
        response.sendRedirect(url);
    }

    /**
     * 获取浏览器参数
     * @param request
     * @return
     */
    private static String getParam(final HttpServletRequest request) throws UnsupportedEncodingException {
        final StringBuilder sb = new StringBuilder();
        final Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            final String name = parameterNames.nextElement();
            sb.append("&");
            sb.append(name);
            sb.append("=");
            final String value = URLEncoder.encode(request.getParameter(name), StandardCharsets.UTF_8.name());
            sb.append(value);
        }
        return sb.toString();
    }

}
